package com.open.capacity.user.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSONObject;
import com.open.capacity.annotation.log.LogAnnotation;
import com.open.capacity.commons.PageResult;
import com.open.capacity.commons.Result;
import com.open.capacity.reimburse.excel.BmExcelModel;
import com.open.capacity.user.model.SysCompany;
import com.open.capacity.user.model.SysDepartment;
import com.open.capacity.user.model.SysPost;
import com.open.capacity.user.service.SysCompanyService;
import com.open.capacity.user.service.SysDepartmentService;
import com.open.capacity.user.vo.SysDepartmentVo;
import com.open.capacity.utils.encrypt.Md5Utils;
import com.open.capacity.vo.MapVo;
import com.open.capacity.vo.TreeVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.list.TreeList;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 作者 ftquan E-mail: 464725602@qq.com
 * @version 创建时间：2017年11月12日 上午22:57:51
 * 部门管理
 */
@RestController
@Api(tags = "部门模块api")
public class SysDepartmentController {

    private static Logger logger = LoggerFactory.getLogger(SysDepartmentController.class);


    @Autowired
    private SysCompanyService companyService;

    @Autowired
    private SysDepartmentService departmentService;

    /**
     * 查询部门
     *
     * @param params
     * @return
     */
    @PreAuthorize("hasAuthority('department:get/departments')")
    @ApiOperation(value = "查询部门")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "companyId", value = "公司id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "parentId", value = "父级id", dataType = "String"),
            @ApiImplicitParam(name = "keyword", value = "关键字", dataType = "String")
    })
    @RequestMapping("/departments")
    public PageResult findDepartments(@RequestParam Map<String, Object> params) {
        PageResult pageResult = departmentService.pageAll(params);
        return pageResult;
    }

    /**
     * 查询部门tree
     *
     * @param companyId
     * @param parentId
     * @return
     */
    @PreAuthorize("hasAuthority('department:get/departments')")
    @ApiOperation(value = "查询部门tree")
    @GetMapping("/departments/tree")
    public Result<List<TreeVo>> treeDepartments(@RequestParam(value = "companyId", required = false) String companyId, @RequestParam(value = "parentId", defaultValue = "0") String parentId) {
        Map<String, Object> params = new HashMap<>();
        params.put("companyId", companyId);
        params.put("status", 1);
        List<SysDepartment> departments = departmentService.findDepartments(params);
        List<TreeVo> treeList = new TreeList();
        departments.forEach(m -> {
            TreeVo node = new TreeVo();
            node.setId(m.getId());
            node.setText(m.getFullName());
            node.setValue(m.getId().toString());
            node.setShowcheck(false);
            node.setCheckstate(0);
            node.setIsexpand(false);
            node.setComplete(false);
            node.setParentId(m.getParentId());
            treeList.add(node);
        });

        return Result.succeed(TreeVo.RecursiveBuilder(treeList, parentId));
    }

    /**
     * 查询组织架构tree
     *
     * @param companyId
     * @param parentId
     * @return
     */
    @PreAuthorize("hasAuthority('department:get/departments')")
    @ApiOperation(value = "查询组织架构tree")
    @GetMapping("/orgs/tree")
    public Result<List<TreeVo>> treeOrgs(@RequestParam(value = "companyId", required = false) String companyId, @RequestParam(value = "parentId", defaultValue = "0") String parentId) {
        Map<String, Object> params = new HashMap<>();
        List<SysCompany> companys = companyService.findCompanys(params);
        List<TreeVo> treeList = new TreeList();
        companys.forEach(m -> {
            TreeVo node = new TreeVo();
            node.setShowcheck(true);
            node.setId(m.getId());
            node.setText(m.getFullName());
            node.setValue(m.getId().toString());
            node.setCheckstate(0);
            if (m.getParentId().equals("0")) {
                node.setIsexpand(true);
            } else {
                node.setIsexpand(false);
            }
            node.setComplete(false);
            node.setParentId(m.getParentId());
            treeList.add(node);
        });

        params.put("companyId", companyId);
        List<SysDepartment> departments = departmentService.findDepartments(params);
        departments.forEach(m -> {
            TreeVo node = new TreeVo();
            node.setShowcheck(true);
            node.setId(m.getId());
            node.setText(m.getFullName());
            node.setValue(m.getId().toString());
            node.setCheckstate(0);
            node.setIsexpand(false);
            node.setComplete(false);
            if (m.getParentId() == null || m.getParentId().equals("0")) {
                node.setParentId(m.getCompanyId());
            } else {
                node.setParentId(m.getParentId());
            }

            treeList.add(node);
        });

        return Result.succeed(TreeVo.RecursiveBuilder(treeList, parentId));
    }


    /**
     * 查询部门map
     *
     * @param ver
     * @return
     */
    @PreAuthorize("hasAuthority('department:get/departments')")
    @ApiOperation(value = "查询部门map")
    @GetMapping("/departments/map")
    public Result<MapVo> mapCompanys(@RequestParam(value = "ver", required = false) String ver) {
        Map<String, SysDepartmentVo> departmentMaps = departmentService.getMap();
        String md5 = JSONObject.toJSONString(departmentMaps);
        if (md5.equals(ver)) {
            return Result.succeed("NO UPDATE");
        }
        MapVo<Map<String, SysDepartmentVo>> vo = new MapVo();
        vo.setData(departmentMaps);
        vo.setVer(Md5Utils.hash(md5));
        return Result.succeed(vo);
    }

    @GetMapping("/departments/{id}")
    @PreAuthorize("hasAuthority('department:get/departments')")
    public Result<SysDepartment> findDepartmentById(@PathVariable(value = "id") String id) {
        SysDepartment dept = departmentService.findById(id);
        return Result.succeed(dept);
    }

    /**
     * 查询单条记录
     */
    @RequestMapping("/departments/findByCode")
    @PreAuthorize("hasAuthority('department:get/departments')")
    public Result findByCode(String companyId, String code) {
        return Result.succeed(departmentService.findByCode(companyId, code));
    }

    @GetMapping("/departments/getName")
    @PreAuthorize("hasAuthority('department:get/departments')")
    public Result getName(String companyId, @RequestParam(value = "keyValue") String keyValue) {
        SysDepartment bm = departmentService.findByCode(companyId, keyValue);
        return Result.succeed(bm == null ? "" : bm.getCode() + " " + bm.getFullName(), "获取成功！");
    }

    /**
     * 查询下一个code
     */
    @RequestMapping("/departments/findNextCode")
    @PreAuthorize("hasAuthority('department:get/departments')")
    public Result findNextCode(String companyId) {
        return Result.succeed(departmentService.getNextCode(companyId), "成功");
    }

    /**
     * 部门新增或者更新
     *
     * @param sysDepartment
     * @return
     */
    @PreAuthorize("hasAnyAuthority('department:post/departments','department:put/departments')")
    @ApiOperation(value = "保存部门")
    @PostMapping("/departments/saveOrUpdate")
    @LogAnnotation(module = "部门", name = "更新")
    public Result saveOrUpdate(@RequestBody SysDepartment sysDepartment, String keyValue) {

        try {
            departmentService.saveOrUpdate(sysDepartment, keyValue);
            return Result.succeed("保存成功");
        } catch (Exception e) {

            return Result.failed(e.getMessage());
        }

    }

    /**
     * 删除部门
     * delete /department/1
     *
     * @param id
     */
    @PreAuthorize("hasAuthority('department:delete/departments/{id}')")
    @ApiOperation(value = "删除部门")
    @DeleteMapping("/departments/{id}")
    @LogAnnotation(module = "部门", name = "删除")
    public Result delete(@PathVariable(value = "id") String id) {
        try {
            departmentService.delete(id);
            return Result.succeed("操作成功");
        } catch (Exception e) {
            return Result.failed(e.getMessage());
        }
    }

    /**
     * 导出数据
     *
     * @return
     */
    @GetMapping("/departments/exportExcel")
    @PreAuthorize("hasAuthority('department:post/departments/export')")
    public void export(@RequestParam Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) {
        List<BmExcelModel> result = departmentService.findExcels(params);

        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment;filename=departments.xls");
        OutputStream ouputStream = null;
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("部门", "部门"),
                BmExcelModel.class, result);
        try {
            ouputStream = response.getOutputStream();
            workbook.write(ouputStream);
        } catch (Exception e) {
            throw new RuntimeException("系统异常");
        } finally {
            try {
                if (ouputStream != null) {
                    ouputStream.flush();
                    ouputStream.close();
                }
            } catch (Exception e) {
                throw new RuntimeException("系统异常");
            }
        }
    }

    /**
     * 导入excel
     */
    @PostMapping("/departments/importExcel")
    @PreAuthorize("hasAnyAuthority('department:departments:import')")
    @LogAnnotation(module = "部门", name = "导入excel")
    public Result importExcel(String companyId, @RequestParam("file") MultipartFile multipartFile) throws Exception {
        int count = departmentService.importExcel(multipartFile, companyId);
        return Result.succeed(count, "导入成功");
    }
}
